package com.lpc.framework.service;

import java.util.List;


import jodd.bean.BeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.util.StringUtils;

import tk.mybatis.mapper.entity.Example;

import com.github.pagehelper.PageHelper;
import com.lpc.framework.base.CommonMapper;
import com.lpc.framework.search.Searchable;
import com.lpc.framework.search.util.SearchHelper;
import com.lpc.framework.util.ReflectUtil;

/**
 * 公共service，提供了各种常用方法封装
 * 
 * @author jiangjinlong
 * @param <T>
 *
 */
public abstract class CommonService<T> {

    protected final Class<T> entityClass;

    protected CommonService() {
        this.entityClass = ReflectUtil.findParameterizedType(getClass(), 0);
    }

    public T convertData(T data, boolean isInsert) {
        return data;
    }

    @Autowired
    protected CommonMapper<T> commonMapper;

    /**
     * 保存,null字段不会保存
     * 
     * @param record
     * @return
     */
    public int insert(T record) {
        return commonMapper.insertSelective(convertData(record, true));
    }

    /**
     * 根据主键更新
     * 
     * @param record
     * @return
     */
    public int modifyById(T record) {
        return commonMapper.updateByPrimaryKeySelective(convertData(record, false));
    }

    /**
     * Example作为条件更新
     * 
     * @param record
     * @param example
     * @return
     */
    public int modifyByExample(T record, Example example) {
        return commonMapper.updateByExampleSelective(convertData(record, false), example);
    }

    /**
     * 单表分页查询
     * 
     * @param T record
     * @param pageNum
     * @param pageSize
     * @return
     */
    public List<T> getPage(T record, Pageable page) {
        PageHelper.startPage(page.getPageNumber(), page.getPageSize());
        // Spring4支持泛型注入
        return commonMapper.select(record);
    }

    public List<T> getPageExample(Example example, Pageable page) {
        PageHelper.startPage(page.getPageNumber(), page.getPageSize());
        return commonMapper.selectByExample(example);
    }

    /**
     * 条件过于复杂的查询，不推荐使用此方法
     * 
     * @param searchable
     * @return
     */
    public Page<T> getPageExample(Searchable searchable) {
        Example example = new Example(entityClass);
        SearchHelper helper = new SearchHelper();
        PageHelper.startPage(searchable.getPage().getPageNumber() + 1, searchable.getPage().getPageSize());
        String order = helper.prepareOrder(searchable);
        if (!StringUtils.isEmpty(order)) {
            PageHelper.orderBy(order);
        }
        helper.invokeExample(example, searchable);
        List<T> list = commonMapper.selectByExample(example);
        com.github.pagehelper.Page<T> page = (com.github.pagehelper.Page<T>) list;
        searchable.setPage(page.getPageNum(), page.getPageSize());
        return new PageImpl<T>(page.getResult(), searchable.getPage(), page.getTotal());
    }

    /**
     * 根据条件查询一个
     * 
     * @param record
     * @return
     */
    public T findOne(T record) {
        return commonMapper.selectOne(record);
    }

    /**
     * 根据主键查询
     * 
     * @param key
     * @return
     */
    public T findById(Object key) {
        return commonMapper.selectByPrimaryKey(key);
    }

    /**
     * 根据主键查询
     * 
     * @param key
     * @return
     */
    public T findByIdAndYn(Object id) {
        Example example = new Example(entityClass);
        example.createCriteria().andEqualTo("id", id).andEqualTo("yn", 0);
        List<T> list = commonMapper.selectByExample(example);
        return list.isEmpty() ? null : list.get(0);
    }

    /**
     * 根据条件查询
     * 
     * @param example
     * @return
     */
    public T findOneByExample(Example example) {
        List<T> list = findByExample(example);
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    /**
     * 根据条件查询
     * 
     * @param example
     * @return
     */
    public List<T> findByExample(Example example) {
        return commonMapper.selectByExample(example);
    }

    /**
     * 等于条件查询
     * 
     * @param record
     * @return
     */
    public List<T> find(T record) {
        return commonMapper.select(record);
    }

    /**
     * 查询全部
     * 
     * @param record
     * @return
     */
    public List<T> findAll() {
        return commonMapper.selectAll();
    }

    /**
     * 等于条件，查询总数
     * 
     * @param record
     * @return
     */
    public int count(T record) {
        return commonMapper.selectCount(record);
    }

    /**
     * 高级条件，查询总数
     * 
     * @param example
     * @return
     */
    public int countByExample(Example example) {
        return commonMapper.selectCountByExample(example);
    }

    /**
     * 根据主键删除
     * 
     * @param key
     * @return
     */
    public int removeById(Object key) {
        return commonMapper.deleteByPrimaryKey(key);
    }

    /**
     * 条件相等删除
     * 
     * @param record
     * @return
     */
    public int remove(T record) {
        return commonMapper.delete(record);
    }

    /**
     * 删除，高级条件，例如in
     * 
     * @param example
     * @return
     */
    public int removeExample(Example example) {
        return commonMapper.deleteByExample(example);
    }

    @SuppressWarnings("unchecked")
    public int logicalDeletion(Example example) {
        example.getOredCriteria().get(0).andEqualTo("yn", 0);
        T record = null;
        try {
            record = (T) Class.forName(entityClass.getName()).newInstance();
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        BeanUtil.setProperty(record, "yn", "1");
        return commonMapper.updateByExampleSelective(record, example);
    }
}
